package SMUVE;

import java.io.*;
import java.net.*;
import java.util.concurrent.*;
import static SMUVE.Debug.*;

public class Msg_Pipe {
	private ObjectOutputStream out;
	private ObjectInputStream in;
	private DataOutputStream out_stream;
	private DataInputStream in_stream;
	public static final String delimiter = "|";

	public Msg_Pipe(Socket sock) throws IOException {
		out = new ObjectOutputStream(sock.getOutputStream());
		in = new ObjectInputStream(sock.getInputStream());
		out_stream = new DataOutputStream(sock.getOutputStream());
		in_stream = new DataInputStream(sock.getInputStream());
	}

	/* Public methods */
	public int available() throws IOException {
		return(in_stream.available());
	}
		
	public static String get_delimiter() {
		return(delimiter);
	}

	public boolean send_message(String msg) {
		boolean retval = true;

		try {
			out_stream.writeUTF(msg);
		}
		catch (IOException e) {
			retval = false;
		}

		return(retval);
	}

	public String recv_message() throws IOException {
		return(in_stream.readUTF());
	}

	public String send_recv_message(String msg) throws IOException {
		String retval = "";

		synchronized (this) {
			debug("sending message");
			send_message(msg);
			debug("receiving message");
			retval = recv_message();
			debug("done message");
		}

		return(retval);
	}

	public static String get_message_type(String str) {
		String res[] = str.split("\\" + delimiter);
		return(res[0]);
	}

	public static String get_message_body(String str) {
		int index = str.indexOf(delimiter);
		String ret = "";

		if (index >= 0 && index <= str.length())
			ret = str.substring(index + 1);  // start after the delimiter

		return(ret);
	}

	public void close() throws Exception {
		in.close();
		out.close();
	}

	/* Client accessible messages */
	public boolean add_room(Room room) throws IOException {
		String msg = "add_room" + delimiter + room;
		return(send_recv_message(msg).equals("add_room_success"));
	}

	public boolean add_player(Player player) throws IOException {
		String msg = "add_player" + delimiter + player;
		return(send_recv_message(msg).equals("add_player_success"));
	}

	public String get_players() throws IOException {
		String msg = "get_players";
		return(send_recv_message(msg));
	}

	public String get_rooms() throws IOException {
		String msg = "get_rooms";
		return(send_recv_message(msg));
	}

	public String move(String name, String to_room) throws IOException{
		String msg = "move" + delimiter + name + delimiter + to_room;
		return(send_recv_message(msg));
	}

	public String get_room_players(String room) throws IOException {
		String msg = "get_room_players" + delimiter + room;
		return(send_recv_message(msg));
	}

	public String get_portals(String room) throws IOException {
		String msg = "get_portals" + delimiter + room;
		return(send_recv_message(msg));
	}

	public String add_portal(String room, String to_room) throws IOException {
		String msg = "add_portal" + delimiter + room + delimiter + to_room;
		return(send_recv_message(msg));
	}
		
	/* Private methods */
	private synchronized boolean send_msg(Command cmd) throws Exception {
		synchronized (cmd) {
			out.writeObject(cmd);
			out.flush();
		}
		return(true);
	}

	private synchronized Command recv_msg() throws Exception {
		return((Command) in.readObject());
	}

	private synchronized Command send_recv_msg(Command cmd) throws Exception {
		send_msg(cmd);
		return(recv_msg());
	}

}
